package com.htbb.common.util.security;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import com.alibaba.fastjson.JSON;
import com.htbb.common.base.exception.BizException;
import com.htbb.common.util.MD5Util;

public class SignUtil {
	private static final String signParamName = "sign";
	
	/**
	 * 校验sign参数的值
	 * @param jsonStr
	 * @param password
	 * @param charset
	 * @return true:校验通过 false：校验不通过
	 * @throws Exception 
	 */
	public static final boolean checkSign(Map<String, Object> paramMap, String password, String charset){
        if(!paramMap.containsKey(signParamName))
        	throw new BizException("签名参数" + signParamName + "缺失！");
		TreeMap<String, Object> treeMap = new TreeMap<String, Object>(paramMap);
        return paramMap.get(signParamName).toString().toUpperCase().equals(generateSign(treeMap, password, charset));
	}
	
	/**
	 * 请求接口的签名字段（sign）的生成，按参数名排序按key1=value1&key2=value2…拼接，
	 * @param jsonStr
	 * @param password
	 * @param charset
	 * @return
	 */
	public static final String generateSign(String jsonStr, String password, String charset){
		Map<String, Object> paramMap = JSON.parseObject(jsonStr);
        TreeMap<String, Object> treeMap = new TreeMap<String, Object>(paramMap);
        return generateSign(treeMap, password, charset);
	}
	
	/**
	 * 请求接口的签名字段（sign）的生成规则：参与签名的字段为相应请求接口中除sign之外的所有字段与访问密钥
	 * @param msgParams
	 * @param password
	 * @param charset
	 * @return
	 */
	public static final String generateSign(SortedMap<String, Object> msgParams, String password, String charset) {
		StringBuffer sb = new StringBuffer();
		Set<?> es = msgParams.entrySet();
		Iterator<?> it = es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry)it.next();
			String k = entry.getKey().toString();
			String v = entry.getValue().toString();
			if (!signParamName.equals(k)) {
				sb.append(k + "=" + v + "&");
			}
		}
		sb.append("password=" + password);
		String sign = MD5Util.MD5Encode(sb.toString(), charset).toUpperCase();
		return sign;
	}
}
